package com.hccl.service.update;

import com.hccl.service.parser.Parser;
import com.hccl.service.parser.ParserPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 更新流程文件，和更新别
 */
@Component
public class UpdateProcesses {

    @Autowired
    UpdateOptions updateOptions;

    @Autowired
    ParserPool parserPool;

    private final static Logger LOGGER = LoggerFactory.getLogger(UpdateProcesses.class);

    //更新流程用的锁
    private final static ReentrantLock UPDATElABELLOCk = new ReentrantLock(false);

    //更新文件夹结束的标识
    private final static ReentrantLock UPDATEPROCESSESLOCK = new ReentrantLock(false);

    public Set numSet = Collections.synchronizedSet(new HashSet<>());

    /**
     * 更新流程具体执行方法
     *
     * @return
     */
    public boolean updateProcessAction() throws Exception {
        if (isUpdating()) {
            return false;
        }

        UPDATElABELLOCk.lock();
        try {
            updateOptions.backupProcessFile();
        } catch (Exception e) {
            LOGGER.error("【备份流程文件失败!】" + e);
            UPDATElABELLOCk.unlock();
            return false;
        }

        //从数据库更新最新流程
        UPDATEPROCESSESLOCK.lock();
        try {
            updateOptions.updateCorpusAndProcessFromDB();
            parserPool.updateDialogManager();
        } catch (Exception e) {
            LOGGER.error("【更新流程出错!】" + e);
            return false;
        } finally {
            UPDATEPROCESSESLOCK.unlock();
        }

        //更新流程
        List<Parser> oldParsers = new ArrayList<>();
        parserPool.getPool().drainTo(oldParsers);

        int num = parserPool.getConstants().getPoolSize();
        for (int i = 0; i < num; i++) {
            numSet.add(Integer.valueOf(i));
        }
        //更新流程文件到对象类
        try {
            for (Parser parser :
                    oldParsers) {
                parser.setDialogManager(parserPool.getDialogManager());
                parser.getSimilarityUtil().updateSimilarityMap();
                LOGGER.info("【更新id为" + parser.getId() + "的parser】");
                parserPool.add(parser);
                numSet.remove(parser.getId());
            }
            if (!numSet.isEmpty()) {
                LOGGER.info("【ParserPool中未更新的parser的id集合为" + numSet + "】");
            } else {
                LOGGER.info("【ParserPool中的parser全部更新完成！】");
            }
        } catch (Exception e) {

        }

        UPDATElABELLOCk.unlock();
        return true;
    }

    public void updateParser(Parser parser) {
        parser.setDialogManager(parserPool.getDialogManager());
        numSet.remove(parser.getId());
        LOGGER.info("【更新id为:"+parser.getId()+"的parser！】");
        if (numSet.isEmpty()) {
            LOGGER.info("【parserPool中全部parser更新完成！】");
            UPDATEPROCESSESLOCK.unlock();
        }
    }

    public boolean isUpdating() {
        return UPDATElABELLOCk.isLocked();
    }

    public boolean isUpdateProcess() {
        return UPDATEPROCESSESLOCK.isLocked();
    }
}
